<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
class filtergrid extends CI_Model {

	var $select   =array();
	var $join     =array();
	var $where    =array();
	var $where_in =array();
	var $order_by =array();
	var $group_by =array();
	var $primary  =array();
	var $from     =NULL;
	var $d        =array();
	var $dbgroup  ='default';

	function __construct($d=FALSE,$dbgroup='default'){
		parent::__construct();
		$this->d=$d;

		if($dbgroup!='default'){
			$this->dbgroup=$dbgroup;
			$this->db=$this->load->database($dbgroup,true);
		}

	}

	function select($param){
		if(is_array($param))
		$this->select=$param;
		else
		$this->select=func_get_args($param);
	}

	function join($param){
			$this->join[]=func_get_args($param);
	}

	function where($param){
			$this->where[]=func_get_args($param);
	}

	function where_in($param){
			$this->where_in[]=func_get_args($param);
	}

	function order_by($param){
			$this->order_by[]=func_get_args($param);
	}

	function group_by($param){
			$this->group_by[]=func_get_args($param);
	}

	function from($param){
		$this->from=$param;
	}

	function build(&$data,&$page,&$cant,&$rows){
		//		$this->load->library('xml');
		$this->load->library('util');

		$page         =(isset($this->d['page']        ) ? $this->d['page']        :'0'    );
		$rows         =(isset($this->d['rows']        ) ? $this->d['rows']        :null   );
		$sidx         =(isset($this->d['sidx']        ) ? $this->d['sidx']        :1      );
		$sord         =(isset($this->d['sord']        ) ? $this->d['sord']        :'desc' );
		$searchField  =(isset($this->d['searchField'] ) ? $this->d['searchField'] :'id'   );
		$searchString =(isset($this->d['searchString']) ? $this->d['searchString']:''     );
		$searchOper   =(isset($this->d['searchOper']  ) ? $this->d['searchOper']  :'gt'   );
		$searchOn     =(isset($this->d['_search']     ) ? $this->d['_search']     :'false');
		$filters      =(isset($this->d['filters']     ) ? $this->d['filters']     :'false');

		$this->db->_escape_char='';
		$this->db->_protect_identifiers=false;

		$this->db->select($this->select);
		//if(!empty($searchString)){


		///join
		foreach($this->join as $key=>$value){
			if(count($value)==2)
			$this->db->join($this->join[$key][0],$this->join[$key][1]);
			elseif(count($value)==3)
			$this->db->join($this->join[$key][0],$this->join[$key][1],$this->join[$key][2]);
		}

		//join
		foreach($this->where as $key=>$value)
			$this->db->where($this->where[$key][0],$this->where[$key][1]);

		foreach($this->where_in as $key=>$value)
			$this->db->where_in($this->where_in[$key][0],$this->where_in[$key][1]);

		foreach($this->group_by as $v)
			$this->db->group_by($v);

		$cant = $this->db->count_all($this->from);

		if($searchOn == 'true'){
			$searchstr = $this->Strip($filters);
			$jsona     = json_decode($searchstr,true);
			$wh=$this->getStringForGroup($jsona);
			$this->db->where($wh);
		}
		if($rows){
			if($page>0)
			$this->db->limit($rows,abs($rows*$page-$rows));
			else
			$this->db->limit($rows);
		}

		if($sidx==1){
			foreach($this->order_by as $v)
				$this->db->order_by($v[0],$v[1]);
		}else{
			$this->db->order_by($sidx,$sord);
		}

		$this->db->select($this->select);
		if(isset($this->join)){
			foreach($this->join as $key=>$value){
				if(count($value)==2)
				$this->db->join($this->join[$key][0],$this->join[$key][1]);
				elseif(count($value)==3)
				$this->db->join($this->join[$key][0],$this->join[$key][1],$this->join[$key][2]);
			}
		}

		foreach($this->where as $key=>$value)
			$this->db->where($this->where[$key][0],$this->where[$key][1]);

		foreach($this->where_in as $key=>$value)
			$this->db->where_in($this->where_in[$key][0],$this->where_in[$key][1]);

		foreach($this->group_by as $v)
			$this->db->group_by($v);


		$result = $this->db->get($this->from);

		$this->db->last_query();

		//$b=$this->db->escape($a);//$this->db->update_string($this->tabla,$data,$where)
		//$this->db->simple_query("UPDATE valores SET valor=$b where nombre='TITULO6'");

		$data=$result->result_array($result);

		if($this->dbgroup!='default')
		$this->db=$this->load->database('default',TRUE);
	}

	function output($id){
			$this->load->library('json');

			$this->build($data,$page,$cant,$rows);

			$json = new Json($data,$id);
			$json->page     = $page;
			$json->t_pages  = ($cant > 0 && $rows > 0 ? ceil($cant/$rows) :0);
			$json->per_page = $cant;
			$json->output();
	}

	function getStringForGroup( $group )
	{

		$i_='';
		$sopt = array('eq' => " = ",'ne' => " <> ",'lt' => " < ",'le' => " <= ",'gt' => " > ",'ge' => " >= ",'bw'=>" {$i_}LIKE ",'bn'=>" NOT {$i_}LIKE ",'in'=>' IN ','ni'=> ' NOT IN ','ew'=>" {$i_}LIKE ",'en'=>" NOT {$i_}LIKE ",'cn'=>" {$i_}LIKE ",'nc'=>" NOT {$i_}LIKE ", 'nu'=>' IS NULL ', 'nn'=>' IS NOT NULL ');
		$s = "(";
		if( isset ($group['groups']) && is_array($group['groups']) && count($group['groups']) >0 )
		{
			for($j=0; $j<count($group['groups']);$j++ )
			{
				if(strlen($s) > 1 ) {
					$s .= " ".$group['groupOp']." ";
				}
				try {
					$dat = $this->getStringForGroup($group['groups'][$j]);
					$s .= $dat;
				} catch (Exception $e) {
					echo $e->getMessage();
				}
			}
		}
		if (isset($group['rules']) && count($group['rules'])>0 ) {
			try{
				foreach($group['rules'] as $key=>$val) {
					if (strlen($s) > 1) {
						$s .= " ".$group['groupOp']." ";
					}
					$groupop=$group['groupOp'];
					$field = $val['field'];
					$op = $val['op'];
					$v = $val['data'];
					if( $op ) {
						//if($groupop=='AND'){
							switch ($op)
							{
								case 'ne':
									//$this->db->where($field.$sopt[$op], $v);
									$s .= $field.' '.$sopt[$op].$this->db->escape($v);
									break;
								case 'bw':
									//$this->db->where($field.$sopt[$op], $v.'%');
									$s .= $field.' '.$sopt[$op].$this->db->escape($v.'%');
									break;
								case 'bn':
									//$this->db->where($field.$sopt[$op], $v.'%');
									$s .= $field.' '.$sopt[$op].$this->db->escape($v.'%');
									break;
								case 'ew':
									//$this->db->where($field.$sopt[$op], '%'.$v);
									$s .= $field.' '.$sopt[$op].$this->db->escape('%'.$v);
									break;
								case 'en':
									//$this->db->where($field.$sopt[$op], '%'.$v);
									$s .= $field.' '.$sopt[$op].$this->db->escape('%'.$v);
									break;
								case 'cn':
									//$this->db->where($field.$sopt[$op], '%'.$v.'%');
									$s .= $field.' '.$sopt[$op].$this->db->escape('%'.$v.'%');
									break;
								case 'nc':
									//$this->db->where($field.$sopt[$op], '%'.$v.'%');
									$s .= $field.' '.$sopt[$op].$this->db->escape('%'.$v.'%');
									break;
								case 'in':{
										$valuesArray = explode(",", $v);
										foreach ($valuesArray as $key => $valor) {
											$valores[] =$this->db->escape(trim($valor));
										}
										//$this->db->where_in($field, $valores);
										$s .= $field.' '.$sopt[$op]."( '".implode(",",$valores)."' )";
									}
									break;
								case 'ni':{
										$valuesArray = explode(",", $v);
										foreach ($valuesArray as $key => $valor) {
											$valores[] =$this->db->escape(trim($valor));
										}
										//$this->db->where_not_in($field, $valores);
										$s .= $field.' '.$sopt[$op]."( '".implode(",",$valores)."' )";
									}
									break;
								case 'nu':
									//$this->db->where($field.' IS NULL');
									$s .= $field.' '.$sopt[$op]." ";
									break;
								case 'nn':
									//$this->db->where($field.' IS NOT NULL');
									$s .= $field.' '.$sopt[$op]." ";
									break;
								default :
									//$this->db->where($field,$v);
									$s .= $field.' '.$sopt[$op].$this->db->escape($v);
									break;
							}
						//}else{
						//	switch ($op)
						//	{
						//		case 'ne':
						//			$this->db->or_where($field.$sopt[$op], $v);
						//			//$s .= $field.' '.$sopt[$op]."'$v%'";
						//			break;
						//		case 'bw':
						//			$this->db->or_where($field.$sopt[$op], $v.'%');
						//			//$s .= $field.' '.$sopt[$op]."'$v%'";
						//			break;
						//		case 'bn':
						//			$this->db->or_where($field.$sopt[$op], $v.'%');
						//			//$s .= $field.' '.$sopt[$op]."'$v%'";
						//			break;
						//		case 'ew':
						//			$this->db->or_where($field.$sopt[$op], '%'.$v);
						//			//$s .= $field.' '.$sopt[$op]."'%$v'";
						//			break;
						//		case 'en':
						//			$this->db->or_where($field.$sopt[$op], '%'.$v);
						//			//$s .= $field.' '.$sopt[$op]."'%$v'";
						//			break;
						//		case 'cn':
						//			$this->db->or_where($field.$sopt[$op], '%'.$v.'%');
						//			//$s .= $field.' '.$sopt[$op]."'%$v'";
						//			break;
						//		case 'nc':
						//			$this->db->or_where($field.$sopt[$op], '%'.$v.'%');
						//			//$s .= $field.' '.$sopt[$op]."'%$v%'";
						//			break;
						//		case 'in':{
						//				$valuesArray = explode(",", $v);
						//				foreach ($valuesArray as $key => $valor) {
						//					$valores[] = trim($valor);
						//				}
						//				$this->db->or_where_in($field, $valores);
						//				//$s .= $field.' '.$sopt[$op]."( '".implode("','",$valuesArray)."' )";
						//			}
						//			break;
						//		case 'ni':{
						//				$valuesArray = explode(",", $v);
						//				foreach ($valuesArray as $key => $valor) {
						//					$valores[] = trim($valor);
						//				}
						//				$this->db->or_where_not_in($field, $valores);
						//				//$s .= $field.' '.$sopt[$op]."( '".implode("','",$valuesArray)."' )";
						//			}
						//			break;
						//		case 'nu':
						//			$this->db->or_where($field.' IS NULL');
						//			break;
						//		case 'nn':
						//			$this->db->or_where($field.' IS NOT NULL');
						//			//$s .= $field.' '.$sopt[$op]." ";
						//			break;
						//		default :
						//			$this->db->or_where($field,$v);
						//			//$s .= $field.' '.$sopt[$op]." '$v' ";
						//			break;
						//	}
						//}
					}
				}
			} catch (Exception $e) 	{
				echo $e->getMessage();
			}
		}
		$s .= ")";

		if ($s == "()") {

			//return array("",$prm); // ignore groups that don't have rules
			return " 1=1 ";
		} else {
			return $s;
		}
	}

	function Strip($value){
		if(get_magic_quotes_gpc() != 0){
			if(is_array($value))
				if ( $this->array_is_associative($value)){
					foreach( $value as $k=>$v)
						$tmp_val[$k] = stripslashes($v);
					$value = $tmp_val;
				}else
					for($j = 0; $j < sizeof($value); $j++)
						$value[$j] = stripslashes($value[$j]);
			else
				$value = stripslashes($value);
		}
		return $value;
	}

	function array_is_associative ($array){
		if ( is_array($array) && ! empty($array)){
			for ( $iterator = count($array) - 1; $iterator; $iterator-- ){
				if ( ! array_key_exists($iterator, $array) ) { return true; }
			}
			return ! array_key_exists(0, $array);
		}
		return false;
	}
}
